import uuid

from flask import (
    Blueprint, g, request, jsonify, send_file
)

from . import event

from . import config

from . import gamefunction

from pathlib import Path

from flaskr.db import get_db

bp = Blueprint('data', __name__, url_prefix='/data')

# region 基础api

def check_param(params, keys):
    for item in params:
        if item not in keys:
            return -1, jsonify({
                'status': -1,
                'msg': f"{item} is lost!"
            })
    return 0, ""

def verify():
    if not g.user:
        return False, jsonify({
            'status': -1,
            'msg': "未登录"
        })
    else:
        return True, ""

def get_unique_id():
    return uuid.uuid4()

# 获取房间信息
@bp.route('/get-rooms', methods=['POST'])
def get_rooms():
    verify_res, msg = verify()
    if not verify_res: return msg

    db = get_db()
    sql = '''
        SELECT 
        room.id, 
        room.name, 
        COUNT(roomplayer.id) AS online
        FROM room
        LEFT JOIN roomplayer ON room.id = roomplayer.id
        GROUP BY room.id, room.name;
        '''
    rooms = db.execute(sql).fetchall()

    room_list = []
    for room in rooms:
        room_list.append({
            'id': room['id'],
            'name': room['name'],
            'online': room['online']
        })

    return jsonify({
        'status': '0',
        'msg': '',
        'rooms': room_list
    })
    

# 创建房间
@bp.route('/create-room', methods=['POST'])
def create_room():
    verify_res, msg = verify()
    if not verify_res: return msg
    data = request.get_json()
    check_res, msg = check_param(['name'], data.keys())
    if check_res == -1: return msg

    db = get_db()

    # 检查房间名是否存在
    sql = "select * from room where name = ?;"
    if db.execute(sql, (data['name'], )).fetchone():
        return jsonify({
            'status': '-1',
            'msg': '房间名存在'
        })
    
    # 创建房间
    sql = "insert into room(name) values(?);"
    db.execute(sql, (data['name'],))
    db.commit()

    # 把房主加入房间
    # 通过房间名获取房间id
    sql = "select id from room where name = ?;"
    db_data = db.execute(sql, (data['name'], )).fetchone()
    sql = "insert into roomplayer(id, username) values(?, ?);"
    db.execute(sql, (db_data['id'], g.user['username']))
    db.commit()

    event.update_room()

    return jsonify({
        'status': 0,
        'msg': '创建成功'
    })

@bp.route('/join-room', methods=['POST'])
def join_room():
    verify_res, msg = verify()
    if not verify_res: return msg
    data = request.get_json()
    check_res, msg = check_param(['id'], data.keys())
    if check_res == -1: return msg
    username = g.user['username']
    db = get_db()

    # 检查房间是否存在
    sql = "select * from room where id = ?;"
    db_data = db.execute(sql, (data['id'], )).fetchone()
    if not db_data:
        return jsonify({
            'status': '-1',
            'msg': '房间不存在'
        })
    
    # 房间是否已开始
    if db_data['gamestatus'] == 1:
        return jsonify({
            'status': '-1',
            'msg': '游戏已开始，请稍后加入'
        })

    # 玩家是否已经在房间中
    sql = "select * from roomplayer where username = ?;"
    if db.execute(sql, (username, )).fetchone():
        return jsonify({
            'status': '-1',
            'msg': '您已在其他房间中，无法加入'
        })
    
    # 加入房间
    sql = "insert into roomplayer(id, username) values(?, ?);"
    db.execute(sql, (data['id'], username))
    db.commit()

    event.update_room()
    event.tongbu(data['id'])

    return jsonify({
        'status': 0,
        'msg': '加入成功'
    })

@bp.route('/leave-room', methods=['POST'])
def leave_room():
    verify_res, msg = verify()
    if not verify_res: return msg
  
    db = get_db()
    username = g.user['username']

    # 查找用户是否在某个房间中
    sql = "select id from roomplayer where username = ?;"
    db_data = db.execute(sql, (username, )).fetchone()
    if not db_data:
        return {
            'status': '-1',
            'msg': '用户未加入房间'
        }

    roomid = db_data['id']

    # 在roomplayer表中删除用户
    sql = "delete from roomplayer where username = ?;"
    db.execute(sql, (username, ))
    
    # 检查房间中是否还有人，没人就删了
    sql = "select * from roomplayer where id = ?;"
    db_data = db.execute(sql, (roomid, )).fetchall()
    gamer_count = len(db_data) if db_data else 0
    if not db_data:
        sql = "delete from room where id = ?;"
        db.execute(sql, (roomid, ))
        # 删除所有聊天记录
        sql = "delete from roommessage where tableid = ?;"
        db.execute(sql, (roomid, ))

    db.commit()

    gamefunction.check_game_status(roomid)
    event.update_room()
    event.tongbu(roomid)

    return jsonify({
        'status': '0',
        'msg': '成功'
    })

# 修改个人信息接口
@bp.route('/change-info', methods=['POST'])
def change_info():
    verify_res, msg = verify()
    if not verify_res: return msg
    data = request.get_json()
    check_res, msg = check_param(['nickedname'], data.keys())
    if check_res == -1: return msg
    username = g.user['username']
    db = get_db()

   
    sql = "update user set nickedname = ? where username = ?;"
    db.execute(sql, (data['nickedname'], username))

    db.commit()
    # 获取一下新的数据返回去
    sql = "select * from user where username = ?;"
    db_data = db.execute(sql, (username, )).fetchone()
    
    return jsonify({
        'status': 0,
        'msg': '修改成功',
        'username': username,
        'nickedname': db_data['nickedname'],
        'headpicture': db_data['headpicture']
    })

@bp.route('/get-userinfo', methods=['POST'])
def get_userinfo():
    verify_res, msg = verify()
    if not verify_res: return msg
    username = g.user['username']
    db = get_db()

    sql = "select nickedname, headpicture from user where username = ?;"
    db_data = db.execute(sql, (username, )).fetchone()

    return jsonify({
        'status': '0',
        'msg': 'ok',
        'username': username,
        'nickedname': db_data['nickedname'],
        'headpicture': db_data['headpicture']
    })

@bp.route('/get-picture', methods=['GET'])
def get_picture():
    id = request.args.get('id', default = 0)
    db = get_db()
    
    # 查找headpicturemap获取文件名
    sql = "select picturename from headpicturemap where id = ?;"
    db_data = db.execute(sql, (id, )).fetchone()

    picturename = db_data['picturename']

    file_path = Path(config.config['path']) / Path(f"resources/{picturename}")
    print("tky: " + str(file_path))
    if not file_path.exists():
        # 数据出现问题，返回默认图片
        sql = "select picturename from headpicturemap where id = 0;"
        db_data = db.execute(sql).fetchone()
        picturename = db_data['picturename']
        file_path = Path(config.config['path']) / Path(f"resources/{picturename}")
    
    return send_file(file_path)
    
    
@bp.route('/upload-picture', methods=['POST'])
def upload_picture():
    verify_res, msg = verify()
    if not verify_res: return msg

    if 'headpicture' not in request.files:
        return jsonify({
            'status': -1,
            'msg': '图片未上传'
        })
    file = request.files['headpicture']
    if file.filename == '':
        return jsonify({
            'status': -1,
            'msg': '图片未上传'
        })
    username = g.user['username']
    db = get_db()

    file_path = Path(file.filename)
    file_path = Path(config.config['path']) / Path('resources') / Path(str(get_unique_id()) + file_path.suffix)

    file.save(file_path)

    sql = "insert into headpicturemap(picturename) values(?);"
    db.execute(sql, (file_path.name, ))

    # 把旧的头像软删除了
    sql = "select headpicture from user where username = ?;"
    db_data = db.execute(sql, (username, )).fetchone()
    if db_data['headpicture'] != 0:
        sql = "update headpicturemap set valid = 0 where id = ?;"
        db.execute(sql, (db_data['headpicture'], ))
    

    sql = "select id from headpicturemap where picturename = ?;"
    db_data = db.execute(sql, (file_path.name, )).fetchone()

    file_id = db_data['id']

    # 修改user表
    
    sql = "update user set headpicture = ? where username = ?;"
    db.execute(sql, (file_id, username, ))

    # 删除掉所有失效的头像
    sql = "delete from headpicturemap where valid = 0;"
    db.execute(sql)
    
    db.commit()

    return jsonify({
        'status': '0',
        'msg': 'ok',
        'headpicture': file_id
    })


@bp.route('/in-room', methods=['POST'])
def in_room():
    verify_res, msg = verify()
    if not verify_res: return msg

    username = g.user['username']
    db = get_db()
    
    sql = "select * from roomplayer where username = ?;"
    db_data = db.execute(sql, (username, )).fetchone()

    if db_data:
        return jsonify({
            'status': '0',
            'msg': 'ok',
            'inroom': 1
        })
    else:
        return jsonify({
            'status': '0',
            'msg': 'ok',
            'inroom': 0
        })


@bp.route('/room-users', methods=['POST'])
def room_users():
    verify_res, msg = verify()
    if not verify_res: return msg

    username = g.user['username']
    db = get_db()

    sql = '''
            select nickedname, user.username, headpicture, isready, drawingstatus, grade, roomplayer.id
            from user, roomplayer
            where user.username = roomplayer.username and roomplayer.id = (
                select id from roomplayer where username = ?
            );
            ''' 
    db_datas = db.execute(sql, (username, )).fetchall()
    if not db_datas:
        return jsonify({
            'status': '-1',
            'msg': '当前用户未在房间中',
            'list': []
        })
    
    roomid = db_datas[0]['id']
    response = []
    current = dict()
    for item in db_datas:
        response.append({
            'nickedname': item['nickedname'],
            'headpicture': item['headpicture'],
            'isready': item['isready'],
            'drawingstatus': item['drawingstatus'],
            'grade': item['grade']
        })
        if item['username'] == username:
            current = response[-1]
            current['username'] = username

    return jsonify({
        'status': '0',
        'msg': 'ok',
        'list': response,
        'current': current,
        'roomid': roomid
    })
    
# endregion


#     verify_res, msg = verify()
#     if not verify_res: return msg
#     data = request.get_json()
#     check_res, msg = check_param(['id'], data.keys())
#     if check_res == -1: return msg
#     username = g.user['username']
#     db = get_db()


# region 游戏内api
@bp.route('/running-game', methods=['POST'])
def running_game():
    # region
    verify_res, msg = verify()
    if not verify_res: return msg
    data = request.get_json()
    username = g.user['username']
    db = get_db()
    # 获取一下id
    sql = "select id from roomplayer where username = ?;"
    try:
        roomid = db.execute(sql, (username, )).fetchone()['id']
    except:
        return jsonify({
            'status': '-1',
            'msg': '用户未加入房间'
        })
    response = dict({
        'status': 0
    })
    # endregion
    isevent = [False, ] # 需要保证数据库数据更新以后再去同步事件
    # 房间不存在的话直接返回
    if not gamefunction.verify_room(roomid):
        return jsonify({
            'status': '-2',
            'msg': '房间不存在'
        })

    if 'ready' in data.keys():
        '''
        ready: {}
        '''
        status, msg = gamefunction.ready(username, isevent)
        if status == '-1':
            return jsonify({
                'status': status,
                'msg': msg
            })

    if 'message' in data.keys():
        # 这里如果有用户回答正确，可以直接将targettime设置为现在，下面的boarddata情况里就会更新词语
        gamefunction.send_message(roomid, username, data['message']['message'], isevent)

    # 如果游戏开始执行下面这部分
    if gamefunction.look_game_status(roomid):

        if 'boarddata' in data.keys():
            gamefunction.update_board(roomid, username, data['boarddata'], isevent)
            
        gamefunction.update_word(roomid, isevent)


    # 获取所有信息，一定是在所有信息都更新完了之后再获取
    status, all_info = gamefunction.game_get_all_info(roomid, username)
    if status == '-1':
        return jsonify({
            'status': status,
            'msg': all_info
        })


    response.update({
        'all_info': all_info,
        'request_user': username
    })
    
    if isevent[0]: event.tongbu(roomid)

    return jsonify(response)
# endregion
